package sad_G211;

import weka.core.ChebyshevDistance;
import weka.core.EuclideanDistance;
import weka.core.Instances;
import weka.core.ManhattanDistance;
import weka.core.SelectedTag;
import weka.core.neighboursearch.LinearNNSearch;

import java.util.Random;

import weka.classifiers.Evaluation;
import weka.classifiers.lazy.IBk;
//import weka.core.Instances;

public class Clasificar3 {
	
	public static void clasificar(Instances data) throws Exception{
		
		//necesitamos mirar cn cuantos vecinos vamos a probar, para k=1-10
		double fm, fmMax = 0, dMax = 0, wMax = 0;
		int kMejor = 0;
		String dis, peso;
		for(int k = 1; k<=10; k++){
			IBk estimador = new IBk(k); 					
			Evaluation evaluator = null;
			
			//Probamos mejor FMeasure por cada k y w
			int valor = 0;
			for(int w=0; w<=2; w++){
				valor = (int) Math.pow(2,w);//Necesitamos porque los valores que toma es en potencia de 2
				estimador.setDistanceWeighting(new SelectedTag((int)valor, IBk.TAGS_WEIGHTING));
				evaluator = new Evaluation(data);
				evaluator.crossValidateModel(estimador, data, 10, new Random(1)); // Random(1): the seed=1 means "no shuffle" :-! porque ya hemos barajao
				
				//Probamos mejor FMeasure por cada k, w y d
				for(int d = 1; d <= 3; d++) {
					LinearNNSearch lnn = new LinearNNSearch();
					switch(d) {
							case 1: lnn.setDistanceFunction(new EuclideanDistance());	
							break;
				
							case 2: lnn.setDistanceFunction(new ManhattanDistance());				
							break;
							
							case 3: lnn.setDistanceFunction(new ChebyshevDistance());
							break;
					}
					estimador.setNearestNeighbourSearchAlgorithm(lnn);
					
					//Solo necesitamos sacar el fMeasure, comprobamos si es mejor cada vez
					fm = evaluator.weightedFMeasure();
						if(fm > fmMax){
							kMejor = k;
							fmMax = fm;
							dMax = d;
							wMax = w;
						}
				}
				
			}
		}
		
		//imprimimos resultados
		System.out.println("Resultados en funci�n del n�mero de vecinos, la distancia y el peso");
		System.out.println("----------------------------------------------------------");
		System.out.println("La f-Measure m�xima es:  " + fmMax + " para k (n�mero vecinos): " + kMejor);
		if(dMax == 1){
			dis = "Euclidea";
		}
		else if(dMax == 2){
			dis = "Manhattan";
		}
		else{
			dis = "Chebyshev";
		}
		System.out.println("Con una distancia de:  " + dis);
		if(wMax == 0){
			peso = "Sin peso";
		}
		else if(wMax == 1){
			peso = "Peso inverso";
		}
		else{
			peso = "Similitud de peso";
		}
		System.out.println("Y una ponderaci�n de:  " + peso);
		System.out.println("----------------------------------------------------------");
		System.out.println("----------------------------------------------------------");
	}
	
}
